﻿using IDCardReaderCZ.Enum;
using IDCardReaderCZ.Struct;
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace IDCardReaderCZ
{
    public class CRT7005Dll
    {
        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET OpenDev(char[] pcFileSavePath);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET Uninit();

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET CtrlShutter(EN_IDS_SHUTTER_TYPE _shutterType, EN_IDS_SHUTTER_CAP _shutterCap);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET GetVersionInfo(int iVerType, byte[] szVersionInfo);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET Move(_IDS_MOVE_POS _Pos, int ulTimeout);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET CardStatus(out int iStatus);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET ReadRF(_IDS_CARD_TYPE _CardType, byte[] pRFResult, int ulTimeout);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET Scan(_IDS_SCAN_CONF _ScanConf, IntPtr pResult);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET CRT7005_ExeCommand(int iSendDataLen, byte[] bySendData, out int iRecvDataLen, byte[] byRecvData);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET SetWhiteBalance();

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET SetParam(short RA, short GA, short BA, short RB, short GB, short BB, int PGAR, int PGAG);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET GetParam(out short RGB_A, out short RGB_B, out int PGAR, out int PGAG);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET FWUpgrader(char[] szPath);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET ScanMRZ(_IDS_SCAN_CONF _ScanConf, IntPtr pResult, byte[] mrzData, out int mrzLen);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET ReadIDDG(char[] Mrz, int nNumber, byte[] pData);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET ReadPic(char[] Mrz, StringBuilder pPath);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET GetSAMID(byte[] samid);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET ResetRF();

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET SendAPDU(byte[] bySendData, int iSendDataLen, byte[] byRecvData, out int iRecvDataLen);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET CRT_GetAvg(char[] inImageData, out int iRecvDataLen);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET Test();

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET ChangeScanType(int iType);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET GetScanType(out int iType);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET Bmp2Jpeg(int lQuality, char[] pcBmpFile, char[] pcJpegFile, bool bDelSrc);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET CRT_CombineImg(char[] comPath, char[] img1, char[] img2, int icomType);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET CRT_SetCardScanStatus(int iType);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET CRT_GetCardScanStatus(out int iType);

        [DllImport("IDSIF.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
        public static extern _IDS_RET ReadAllDGInfo(char[] mrzData, byte[] pInfo);

        public static void raw2IDCardData(byte[] datas, IDCardData IDCard)
        {
            Array.Copy(datas, 1, IDCard.Name, 0, 30);
            Array.Copy(datas, 60, IDCard.Gender, 0, 4);
            Array.Copy(datas, 170, IDCard.Birthday, 0, 10);
            Array.Copy(datas, 70, IDCard.Nation, 0, 4);
            Array.Copy(datas, 403, IDCard.IssueDay, 0, 8);
            Array.Copy(datas, 419, IDCard.ExpireDay, 0, 8);
            Array.Copy(datas, 185, IDCard.Address, 0, 70);
            Array.Copy(datas, 287, IDCard.IDCode, 0, 18);
            Array.Copy(datas, 322, IDCard.Organs, 0, 22);
            Array.Copy(datas, 434, IDCard.PhotoData, 0, 256);
        }

        public static void raw2GATCardData(byte[] datas, IDCardData IDCard)
        {
            Array.Copy(datas, 0, IDCard.aucTypeId, 0, 1);
            Array.Copy(datas, 1, IDCard.Name, 0, 30);
            Array.Copy(datas, 60, IDCard.Gender, 0, 4);
            Array.Copy(datas, 71, IDCard.Birthday, 0, 10);
            Array.Copy(datas, 343, IDCard.IssueDay, 0, 8);
            Array.Copy(datas, 359, IDCard.ExpireDay, 0, 8);
            Array.Copy(datas, 87, IDCard.Address, 0, 70);
            Array.Copy(datas, 263, IDCard.Organs, 0, 22);
            Array.Copy(datas, 420, IDCard.PhotoData, 0, 256);
            Array.Copy(datas, 227, IDCard.IDCode, 0, 18);
        }

        public static void raw2PRTCardData(byte[] datas, IDCardData IDCard)
        {
            Array.Copy(datas, 0, IDCard.aucTypeId, 0, 1);
            Array.Copy(datas, 1, IDCard.Name, 0, 30);
            Array.Copy(datas, 160, IDCard.Gender, 0, 4);
            Array.Copy(datas, 271, IDCard.Birthday, 0, 10);
            Array.Copy(datas, 403, IDCard.IssueDay, 0, 8);
            Array.Copy(datas, 419, IDCard.ExpireDay, 0, 8);
            Array.Copy(datas, 171, IDCard.Address, 0, 10);
            Array.Copy(datas, 323, IDCard.Organs, 0, 22);
            Array.Copy(datas, 448, IDCard.PhotoData, 0, 256);
            Array.Copy(datas, 287, IDCard.IDCode, 0, 18);
        }

        public static int GetAndReadIDCardNew(out IDCardData IDCard)
        {
            byte[] array = new byte[2600];
            byte[] array2 = new byte[250];
            IDCard.Name = new byte[40];
            IDCard.Gender = new byte[10];
            IDCard.Birthday = new byte[20];
            IDCard.Nation = new byte[20];
            IDCard.Address = new byte[200];
            IDCard.IssueDay = new byte[50];
            IDCard.ExpireDay = new byte[50];
            IDCard.IDCode = new byte[50];
            IDCard.Organs = new byte[50];
            IDCard.FPData = new byte[1024];
            IDCard.PhotoData = new byte[1024];
            IDCard.aucNo = new byte[50];
            IDCard.aucTypeId = new byte[10];
            if (ReadRF(_IDS_CARD_TYPE._IDS_CARD_TYPE_ID_CN, array, 1000) == _IDS_RET._IDS_RET_OK)
            {
                if (array[0] == 74)
                {
                    raw2GATCardData(array, IDCard);
                }
                else
                {
                    raw2IDCardData(array, IDCard);
                }
            }
            return -210;
        }

        public static int GetAndReadIDCardStr(out IDCardInfo IDCardStr)
        {
            IDCardStr = new IDCardInfo();
            IDCardStr.Name = string.Empty;
            IDCardStr.Gender = string.Empty;
            IDCardStr.Birthday = string.Empty;
            IDCardStr.Nation = string.Empty;
            IDCardStr.Address = string.Empty;
            IDCardStr.IssueDay = string.Empty;
            IDCardStr.ExpireDay = string.Empty;
            IDCardStr.IDCode = string.Empty;
            IDCardStr.Organs = string.Empty;
            IDCardStr.FPData = new byte[1024];
            IDCardStr.PhotoData = string.Empty;
            IDCardStr.aucNo = string.Empty;
            IDCardStr.aucTypeId = string.Empty;
            IDCardData IDCard;
            int andReadIDCardNew = GetAndReadIDCardNew(out IDCard);
            if (andReadIDCardNew == 0 || andReadIDCardNew == 4)
            {
                IDCardStr.Name = GetWideStr(IDCard.Name);
                IDCardStr.Gender = GetGenderName(GetWideStr(IDCard.Gender));
                IDCardStr.Birthday = GetWideStr(IDCard.Birthday);
                IDCardStr.Nation = GetNationName(GetWideStr(IDCard.Nation));
                IDCardStr.IssueDay = GetWideStr(IDCard.IssueDay);
                IDCardStr.ExpireDay = GetWideStr(IDCard.ExpireDay);
                IDCardStr.Address = GetWideStr(IDCard.Address);
                IDCardStr.IDCode = GetWideStr(IDCard.IDCode);
                IDCardStr.Organs = GetWideStr(IDCard.Organs);
                Array.Copy(IDCard.FPData, 0, IDCardStr.FPData, 0, 1024);
                IDCardStr.PhotoData = GetWideStr(IDCard.PhotoData);
            }
            return andReadIDCardNew;
        }

        public static int ReadIDCardInfoNew(out IDCardData IDCard)
        {
            byte[] array = new byte[2600];
            byte[] array2 = new byte[250];
            IDCard.Name = new byte[40];
            IDCard.Gender = new byte[10];
            IDCard.Birthday = new byte[20];
            IDCard.Nation = new byte[20];
            IDCard.Address = new byte[200];
            IDCard.IssueDay = new byte[50];
            IDCard.ExpireDay = new byte[50];
            IDCard.IDCode = new byte[50];
            IDCard.Organs = new byte[50];
            IDCard.FPData = new byte[1024];
            IDCard.PhotoData = new byte[1024];
            IDCard.aucNo = new byte[50];
            IDCard.aucTypeId = new byte[10];
            if (ReadRF(_IDS_CARD_TYPE._IDS_CARD_TYPE_ID_CN, array, 1000) == _IDS_RET._IDS_RET_OK)
            {
                if (array[0] == 74)
                {
                    raw2GATCardData(array, IDCard);
                }
                else if (array[0] == 73)
                {
                    raw2PRTCardData(array, IDCard);
                }
                else
                {
                    raw2IDCardData(array, IDCard);
                }
                return 0;
            }
            return -210;
        }

        public static int ReadIDCardInfoStr(out IDCardInfo IDCardStr)
        {
            IDCardStr = new IDCardInfo();
            IDCardStr.Name = string.Empty;
            IDCardStr.Gender = string.Empty;
            IDCardStr.Birthday = string.Empty;
            IDCardStr.Nation = string.Empty;
            IDCardStr.Address = string.Empty;
            IDCardStr.IssueDay = string.Empty;
            IDCardStr.ExpireDay = string.Empty;
            IDCardStr.IDCode = string.Empty;
            IDCardStr.Organs = string.Empty;
            IDCardStr.FPData = new byte[1024];
            IDCardStr.PhotoData = string.Empty;
            IDCardStr.aucNo = string.Empty;
            IDCardStr.aucTypeId = string.Empty;
            IDCardData IDCard;
            int num = ReadIDCardInfoNew(out IDCard);
            if (num == 0)
            {
                IDCardStr.Name = GetWideStr(IDCard.Name);
                IDCardStr.Gender = GetGenderName(GetWideStr(IDCard.Gender));
                IDCardStr.Birthday = GetWideStr(IDCard.Birthday);
                IDCardStr.Nation = GetWideStr(IDCard.Nation);
                IDCardStr.IssueDay = GetWideStr(IDCard.IssueDay);
                IDCardStr.ExpireDay = GetWideStr(IDCard.ExpireDay);
                IDCardStr.Address = GetWideStr(IDCard.Address);
                IDCardStr.IDCode = GetWideStr(IDCard.IDCode);
                IDCardStr.Organs = GetWideStr(IDCard.Organs);
                IDCardStr.PhotoData = GetWideStr(IDCard.PhotoData);
                IDCardStr.aucNo = GetWideStr(IDCard.aucNo);
                IDCardStr.aucTypeId = GetWideStr(IDCard.aucTypeId);
            }
            return num;
        }

        private static string GetWideStr(byte[] strArr)
        {
            string @string = Encoding.Default.GetString(strArr);
            return @string.Replace("\0", "");
        }

        public static byte[] hexStr2Bytes(string hex)
        {
            if (hex.Length % 2 != 0)
            {
                return new byte[0];
            }
            byte[] array = new byte[hex.Length / 2];
            for (int i = 0; i < array.Length; i++)
            {
                array[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
            }
            return array;
        }

        public static string byteToHexStr(byte[] bytes, int ilen)
        {
            string text = "";
            if (bytes != null)
            {
                for (int i = 0; i < ilen; i++)
                {
                    text += bytes[i].ToString("X2");
                }
            }
            return text;
        }

        public static string GetGenderName(string code)
        {
            if (code == "1")
            {
                return "男";
            }
            if (code == "2")
            {
                return "女";
            }
            return "-";
        }

        public static string GetNationName(string nationCode)
        {
            switch (nationCode)
            {
                case "01":
                    return "汉";
                case "02":
                    return "蒙古";
                case "03":
                    return "回";
                case "04":
                    return "藏";
                case "05":
                    return "维吾尔";
                case "06":
                    return "苗";
                case "07":
                    return "彝";
                case "08":
                    return "壮";
                case "09":
                    return "布依";
                case "10":
                    return "朝鲜";
                case "11":
                    return "满";
                case "12":
                    return "侗";
                case "13":
                    return "瑶";
                case "14":
                    return "白";
                case "15":
                    return "土家";
                case "16":
                    return "哈尼";
                case "17":
                    return "哈萨克";
                case "18":
                    return "傣";
                case "19":
                    return "黎";
                case "20":
                    return "傈僳";
                case "21":
                    return "佤";
                case "22":
                    return "畲";
                case "23":
                    return "高山";
                case "24":
                    return "拉祜";
                case "25":
                    return "水";
                case "26":
                    return "东乡";
                case "27":
                    return "纳西";
                case "28":
                    return "景颇";
                case "29":
                    return "柯尔克孜";
                case "30":
                    return "土";
                case "31":
                    return "达斡尔";
                case "32":
                    return "仫佬";
                case "33":
                    return "羌";
                case "34":
                    return "布朗";
                case "35":
                    return "撒拉";
                case "36":
                    return "毛难";
                case "37":
                    return "仡佬";
                case "38":
                    return "锡伯";
                case "39":
                    return "阿昌";
                case "40":
                    return "普米";
                case "41":
                    return "塔吉克";
                case "42":
                    return "怒";
                case "43":
                    return "乌孜别克";
                case "44":
                    return "俄罗斯";
                case "45":
                    return "鄂温克";
                case "46":
                    return "崩龙";
                case "47":
                    return "保安";
                case "48":
                    return "裕固";
                case "49":
                    return "京";
                case "50":
                    return "塔塔尔";
                case "51":
                    return "独龙";
                case "52":
                    return "鄂伦春";
                case "53":
                    return "赫哲";
                case "54":
                    return "门巴";
                case "55":
                    return "珞巴";
                case "56":
                    return "基诺";
                default:
                    return "-";
            }
        }

        public static void WriteLogs(string filename, string content)
        {
            string currentDirectory = Directory.GetCurrentDirectory();
            if (!string.IsNullOrEmpty(currentDirectory))
            {
                currentDirectory += "\\Log";
                if (!Directory.Exists(currentDirectory))
                {
                    Directory.CreateDirectory(currentDirectory);
                }
                currentDirectory = currentDirectory + "\\" + filename + DateTime.Now.ToString("yyyy-MM-dd") + ".log";
                if (!File.Exists(currentDirectory))
                {
                    FileStream fileStream = File.Create(currentDirectory);
                    fileStream.Close();
                }
                if (File.Exists(currentDirectory))
                {
                    StreamWriter streamWriter = new StreamWriter(currentDirectory, append: true, Encoding.Default);
                    streamWriter.WriteLine(content);
                    streamWriter.Close();
                }
            }
        }
    }
}
